#!/usr/bin/env node
const path = require("path");
const inquirer = require("inquirer");
const ora = require("ora");
const { execSync } = require("child_process");
const {
  getBrachInfo,
  getFilesChanged,
  handleAdd,
  handleAddAll,
  handleCommit,
  handleCheckout,
  handleMerge,
  handlePush,
  isGitInit,
  gitInit,
  copyFile,
  handleRemoveRemote,
} = require("./gitcli");

let featureList = [
  {
    name: "提交",
    value: "commit",
  },
  {
    name: "合并",
    value: "merge",
  },
];

// 自定义一个promise函数避免回调地狱
async function promisePrompt(questions) {
  return new Promise((resolve, reject) => {
    inquirer.prompt(questions).then(resolve).catch(reject);
  });
}

let args = process.argv.slice(2);

const commitMessage = async (msg = "请输入提交信息") => {
  try {
    let message = await promisePrompt({
      type: "input",
      message: msg,
      name: "message",
    });
    return message.message;
  } catch (error) {
    console.log(error, "ddd");
  }
};

const tryCommit = async () => {
  const spinner = ora("提交中...");

  try {
    let commitStatus = await handleCommit(await commitMessage(), () =>
      spinner.start()
    );
    if (commitStatus) {
      handlePush();
      setTimeout(() => {
        spinner.color = "yellow";
        spinner.text = "代码提交完成";
        spinner.stop();
        console.log("代码提交完成");
      }, 200);
    }
  } catch (err) {
    spinner.stop();
    console.log("提交信息不合法", err.message);
    tryCommit();
  }
};

const tryMerge = async () => {
  const { conflictedFiles } = await getFilesChanged();
  if (conflictedFiles.length > 0) {
    console.log(
      conflictedFiles.join(",") + "存在合并冲突，请手动解决冲突后再提交"
    );
    try {
      tryCommit();
    } catch (error) {
      tryMerge();
      console.log(error.message, "commit error");
    }
    return;
  }
};

// 功能选择
const init = async () => {
  let isInit = await isGitInit();
  if (!isInit) {
    console.log("当前目录不是git仓库,请先初始化git仓库");

    try {
      let initGit = await promisePrompt({
        type: "input",
        message: "输入url地址,初始化git仓库",
        name: "url",
      });
      let res = await gitInit(initGit.url);
      if (res) {
        console.log("初始化成功");
      }
    } catch (error) {
      await handleRemoveRemote();
      console.log("初始化失败", error.message);
    }

    return;
  }

  let whichFeature = await promisePrompt({
    type: "list",
    message: "请选择功能",
    name: "branch",
    choices: featureList,
  });

  const { newFiles, modifiedFiles, deletedFiles } = await getFilesChanged();
  const files = [...newFiles, ...modifiedFiles, ...deletedFiles];
  const { branchList } = await getBrachInfo();
  if (whichFeature.branch === "commit") {
    if (files.length === 0) {
      console.log("暂无文件需要提交");
      return;
    }
    // 选择部分提交还是全部提交
    let commitType = await promisePrompt({
      type: "list",
      message: "请选择提交类型",
      name: "commitType",
      choices: [
        { name: "全部提交", value: "all" },
        { name: "部分提交", value: "part" },
      ],
    });
    if (commitType.commitType === "all") {
      console.log(files, "files");
      await handleAddAll();
      await tryCommit();
    } else {
      let commitFiles = await promisePrompt({
        type: "checkbox",
        message: "请选择要提交的文件",
        name: "files",
        choices: files.map((item) => ({ name: item, value: item })),
      });
      await handleAdd(commitFiles.files);
      await tryCommit();
    }
  }

  if (whichFeature.branch === "merge") {
    //选址源分支
    let sourceBranch = await promisePrompt({
      type: "list",
      message: "请选择源分支",
      name: "sourceBranch",
      choices: branchList,
    });
    // 选址目标分支
    let targetBranch = await promisePrompt({
      type: "list",
      message: "请选择目标分支",
      name: "targetBranch",
      choices: branchList,
    });
    // 切换源分支并合并
    try {
      await handleCheckout(sourceBranch.sourceBranch);
      let mergeStatus = await handleMerge(targetBranch.targetBranch);
      if (mergeStatus.files.length > 0) {
        await tryCommit();
        return;
      }
      console.log("没有需要合并的文件");
    } catch (error) {
      //   判断是否有合并冲突
      const { conflictedFiles } = await getFilesChanged();
      if (conflictedFiles.length > 0) {
        await tryMerge();
      } else {
        await tryCommit();
      }
    }
    // await handleCommit(await commitMessage());
  }
};
// 初始化commitizen
const initCommitizen = async () => {
  const spinner = ora("安装中...");
  spinner.start();
  let res = await execSync("npm install commitizen -g");
  if (res) {
    spinner.color = "yellow";
    spinner.text = "安装完成";
    spinner.stop();
    await execSync(
      "commitizen init cz-conventional-changelog --save-dev --save-exact"
    );
    // 修改package.json
    let packageJson = require(`${process.cwd()}/package.json`);
    packageJson.scripts.commit = "git-cz";
    packageJson.config = {
      commitizen: {
        path: "cz-conventional-changelog",
      },
    };
    console.log("安装及初始化完成");
  }
};
// 初始化husky
const initHusky = async () => {
  // 安装husky
  const spinner = ora("安装中...");
  spinner.start();
  let res = await execSync("npm install husky chalk@4 --save-dev");
  if (res) {
    spinner.color = "yellow";
    spinner.text = "安装完成";
    spinner.stop();
    // 初始化husky
    await execSync("npx husky init");

    copyFile(
      path.join(__dirname, "/template/commit-msg"),
      `${process.cwd()}/.husky/commit-msg`
    );
    copyFile(
      path.join(__dirname, "/template/commitValide.js"),
      `${process.cwd()}/.husky/commitValide.js`
    );

    // 删除pre-commit文件
    await execSync("rm -rf .husky/pre-commit");
    console.log("安装及初始化完成");
  }
};

if (!args[0]) {
  init();
}

if (args[0] === "add") {
  let plugins = args[1];
  // 集成husky
  if (plugins === "husky") {
    initHusky();
  }
  if (plugins == "commitizen") {
    initCommitizen();
  }
}
